﻿//_______________________________________________________________________________________________________________________
// Copy Right (c) 2010, 2011 SapiensIT Consulting GmbH, all rights reserved
//_______________________________________________________________________________________________________________________
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//_______________________________________________________________________________________________________________________
// PROJECT:     sapiens.at.SharePoint (SharePoint 2010/V4)
//_______________________________________________________________________________________________________________________
// VERSION:     2.0
//_______________________________________________________________________________________________________________________
// DESCRIPTION: 
//_______________________________________________________________________________________________________________________
// LICENSE:     Different licens Types apply to different file types:
//               - Source code files are governed by the MICROSOFT PUBLIC LICENSE (Ms-PL)
//               - Binary files are governed by MSDN CODE GALLERY BINARY LICENSE
//               - Documentation files are governed by CREATIVE COMMONS ATTRIBUTION 3.0 LICENSE
//
//               The licenses can be found at the projects source location.
//               If you do not agree, don't use it!
// 
//_______________________________________________________________________________________________________________________
// Start SharePoint Branding, visit http://www.cliggin.com! Visit us on http://www.sapiens.at! Tell your friends! 
//_______________________________________________________________________________________________________________________
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Sapiens.at.SharePoint.Extensions;
using Sapiens.at.SharePoint.Entities;

namespace Sapiens.at.SharePoint.Security
{
    /// <summary>
    /// Helper class for methods dealing with permissions.
    /// </summary>
    public static class Permissions
    {
        /// <summary>
        /// Runs a method in a context with elevated privileges.
        /// </summary>
        /// <seealso cref="SPSecurity.RunWithElevatedPrivileges"/>
        /// <param name="item">The listitem the pass privileged</param>
        /// <param name="callback">The callback method</param>
        public static void RunWithElevatedPrivileges(SPListItem item, Action<SPWeb, SPListItem> callback)
        {
            RunWithElevatedPrivileges(item.Web.Site.ID, item.Web.ID, item, callback);
        }

        /// <summary>
        /// Runs a method in a context with elevated privileges.
        /// </summary>
        /// <seealso cref="SPSecurity.RunWithElevatedPrivileges"/>
        /// <param name="web">The current web which will be passed privileged</param>
        /// <param name="callback">The callback method</param>
        public static void RunWithElevatedPrivileges(SPWeb web, Action<SPWeb, SPListItem> callback)
        {
            RunWithElevatedPrivileges(web.Site.ID, web.ID, null, callback);
        }

        /// <summary>
        /// Runs a method in a context with elevated privileges.
        /// </summary>
        /// <seealso cref="SPSecurity.RunWithElevatedPrivileges"/>
        /// <param name="siteId">The ID of the current site</param>
        /// <param name="webId">The ID of the current web which will be passed privileged</param>
        /// <param name="item">The listitem the pass privileged</param>
        /// <param name="callback">The callback method</param>
        public static void RunWithElevatedPrivileges(Guid siteId, Guid webId, SPListItem item, Action<SPWeb, SPListItem> callback)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (var privilegedSite = new SPSite(siteId))
                {
                    using (var privilegedWeb = privilegedSite.OpenWeb(webId))
                    {
                        SPListItem privilegedItem = null;
                        if (item != null && item.ID != 0 && !item.IsCheckedOut())
                        {
                            privilegedItem = privilegedWeb.GetListItem(SPUrlUtility.CombineUrl(privilegedWeb.Url, item.Url));
                        }
                        callback(privilegedWeb, privilegedItem);
                    }
                }
            });
        }

        /// <summary>
        /// Runs a method in a context with elevated privileges.
        /// </summary>
        /// <param name="siteId">The ID of the current site</param>
        /// <param name="webId">The ID of the current web which will be passed privileged</param>
        /// <param name="itemId">The ID of the listitem to pass privileged</param>
        /// <param name="callback">The callback method</param>
        /// <param name="listId">The ID of the list of the listitem</param>
        public static void RunWithElevatedPrivileges(Guid siteId, Guid webId, Guid listId, int itemId, Action<SPListItem> callback)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (var privilegedSite = new SPSite(siteId))
                {
                    using (var privilegedWeb = privilegedSite.OpenWeb(webId))
                    {
                        SPListItem privilegedItem = null;
                        var list = privilegedWeb.Lists[listId];
                        if (itemId > 0)
                        {
                            privilegedItem = list.GetItemById(itemId);
                            if (privilegedItem.IsCheckedOut()) { privilegedItem = null; }
                        }
                        callback(privilegedItem);
                    }
                }
            });
        }

        /// <summary>
        /// Runs a method in a context with elevated privileges.
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="entity"></param>
        /// <param name="callback"></param>
        public static void RunWithElevatedPrivileges<TEntity>(TEntity entity, Action<TEntity> callback)
            where TEntity : IEntity
        {
            SPSecurity.RunWithElevatedPrivileges(() =>
            {
                using (var pSite = new SPSite(entity.Web.Site.ID))
                {
                    using (var pWeb = pSite.OpenWeb(entity.Web.ID))
                    {
                        SPListItem pItem = null;
                        var pList = pWeb.Lists[entity.List.ID];
                        if (entity.Id > 0)
                        {
                            pItem = pList.GetItemById(entity.Id);
                            if (pItem.IsCheckedOut()) { pItem = null; }
                        }
                        TEntity pEntity = default(TEntity);
                        if (pItem != null)
                        {
                            pEntity = ListItemMapper.GetEntity<TEntity>(pItem);
                        }
                        else
                        {
                            pEntity = ListItemMapper.GetEntity<TEntity>(entity.Id, entity.Title, pList);
                        }
                        callback(pEntity);
                    }
                }
            });
        }
    }
}
